//
//  SHAudienceLiveView.m
//  Netease
//
//  Created by 王方伟 on 2017/8/31.
//  Copyright © 2017年 wfw. All rights reserved.
//

#import "SHAudienceLiveView.h"
#import "NTESSessionMsgConverter.h"
#import "NTESLiveAudienceHandler.h"
#import "NTESAudienceConnectView.h"
#import "NSDictionary+Extension.h"
#import "NELivePlayerController.h"
#import "NTESInteractSelectView.h"
#import "NTESPresentAttachment.h"
#import "NSString+Extension.h"
#import "NTESLikeAttachment.h"
#import "NTESLiveInnerView.h"
#import "NTESBundleSetting.h"
#import "NTESMicAttachment.h"
#import "NTESLiveManager.h"
#import "NTESDemoService.h"
#import "NTESUserUtil.h"
#import <NIMSDK/NIMSDK.h>
#import <NIMAVChat/NIMAVChat.h>

typedef void(^NTESLivePlayerShutdownHandler)(void);

@interface SHAudienceLiveView ()<NTESLiveInnerViewDelegate, NIMChatManagerDelegate, NTESAudienceConnectDelegate, NTESInteractSelectDelegate, NIMNetCallManagerDelegate, NIMSystemNotificationManagerDelegate, NIMChatroomManagerDelegate, NTESLiveAudienceHandlerDelegate>
@property (strong, nonatomic)  UIView *canvas;
@property (nonatomic,strong) NELivePlayerController *player;
@property (nonatomic, strong) NTESLiveInnerView *innerView;
@property (nonatomic,strong) NSMutableSet<NTESLivePlayerShutdownHandler> *shutdownHandlers;
@property (strong, nonatomic) NTESLiveAudienceHandler *handler;
@property (nonatomic, strong) NTESAudienceConnectView *connectingView;

@property (copy, nonatomic) NSString *chatroomId;
@property (copy, nonatomic) NSString *streamUrl;
@property (assign, nonatomic) BOOL isShutdowning;
@property (assign, nonatomic) BOOL isPlaying;
@property (assign, nonatomic) BOOL isMute;
@property (assign, nonatomic) BOOL isNextPlayer;
@end

@implementation SHAudienceLiveView

+ (instancetype)audienceLiveView{
    return [[SHAudienceLiveView alloc] init];
}

- (UIView *)canvas{
    if (!_canvas) {
        _canvas = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height )];
        _canvas.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _canvas.contentMode = UIViewContentModeScaleAspectFill;
        _canvas.clipsToBounds = YES;
    }
    return _canvas;
}

- (UIView *)innerView{
    if (!_innerView) {
        _innerView = [[NTESLiveInnerView alloc] initWithChatroom:self.chatroomId frame:self.bounds];
        _innerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _innerView.delegate = self;
    }
    return _innerView;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        [self seupView];
    }
    return self;
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self endEditing:YES];
}

- (void)seupView{
    _chatroomId = [NTESLiveManager sharedLiveManager].chatroomId;
    _streamUrl = [NTESLiveManager sharedLiveManager].streamUrl;
    _shutdownHandlers = [[NSMutableSet alloc] init];
    
    [self addSubview:self.canvas];
    [[NIMSDK sharedSDK].chatroomManager addDelegate:self];
    [[NIMSDK sharedSDK].chatManager addDelegate:self];
    [[NIMSDK sharedSDK].systemNotificationManager addDelegate:self];
    [[NIMAVChatSDK sharedSDK].netCallManager addDelegate:self];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidPlay:) name:NTESLivePlayerFirstVideoDisplayedNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidPlay:) name:NTESLivePlayerFirstAudioDisplayedNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinshed:) name:NTESLivePlayerPlaybackFinishedNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerDidPreparedToPlay:) name:NELivePlayerDidPreparedToPlayNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerPlayBackFinished:) name:NELivePlayerPlaybackFinishedNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerReleaseSueecssed:) name:NELivePlayerReleaseSueecssNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidPlay) name:NELivePlayerFirstVideoDisplayedNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerDidPlay) name:NELivePlayerFirstAudioDisplayedNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerWillBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doExitLive) name:@"DrageViewCloseNotification" object:nil];
    
    [self startPlay];
    //先切到等待界面
    [self addSubview:self.innerView];
    [self.innerView switchToWaitingUI];
    
    [self enterChatroom];
}

- (void)startPlay{
    _isNextPlayer = YES;
    if (self.player) {
        [self.player.view removeFromSuperview];
        [self shutdown];
    }else{
        self.player = [self makePlayer:_streamUrl];
        [_canvas addSubview:self.player.view];
        if (![self.player isPreparedToPlay]) {
            [self.player prepareToPlay];
        }
        _isNextPlayer = FALSE;
    }
    [self.player setScalingMode:NELPMovieScalingModeAspectFit];
}


- (NELivePlayerController *)makePlayer:(NSString *)streamUrl{
    NELivePlayerController *player;
    [NELivePlayerController setLogLevel:NELP_LOG_DEFAULT];
    player = [[NELivePlayerController alloc] initWithContentURL:[NSURL URLWithString:streamUrl]];
    player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    NELPBufferStrategy strategy  = [[NTESBundleSetting sharedConfig] preferredBufferStrategy];
    [player setBufferStrategy:strategy];
    [player setHardwareDecoder:NO];
    [player isLogToFile:YES];
    
    if (!player) {
        [self retry:5];
    }
    return player;
}


- (void)retry:(NSTimeInterval)delay{
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (weakSelf) {
            [weakSelf startPlay];
        }
    });
}

- (BOOL)shutdown{
    if (!self.player) {
        [self fireShutdownHandlers];
        return NO;
    }
    if (_isShutdowning) {
        return NO;
    }
    _isShutdowning = YES;
    [self.player shutdown];
    self.player = nil;
    return YES;
}

- (void)fireShutdownHandlers{
    for (NTESLivePlayerShutdownHandler handler in self.shutdownHandlers) {
        handler();
    }
    [self.shutdownHandlers removeAllObjects];
}

#pragma mark NTESLiveInnerViewDelegate
- (void)didSendText:(NSString *)text{
    NIMMessage *message = [NTESSessionMsgConverter msgWithText:text];
    NIMSession *session = [NIMSession session:_chatroomId type:NIMSessionTypeChatroom];
    [[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
}

- (void)onActionType:(NTESLiveActionType)type sender:(id)sender{
    switch (type) {
        case NTESLiveActionTypeLike://点赞
            break;
            
        case NTESLiveActionTypePresent://礼物
            break;
        
        case NTESLiveActionTypeCamera://旋转摄像头
            break;
            
        case NTESLiveActionTypeInteract://互动
            if ([NTESLiveManager sharedLiveManager].role == NTESLiveRoleAudience){
                if (self.connectingView) {
                    //说明正在请求连接
                    [self.connectingView show];
                }else{
                    NTESInteractSelectView *interact = [[NTESInteractSelectView alloc] initWithFrame:self.bounds];
                    interact.delegate = self;
                    if ([NTESLiveManager sharedLiveManager].type == NIMNetCallMediaTypeVideo) {
                        interact.types = @[@(NIMNetCallMediaTypeVideo),@(NIMNetCallMediaTypeAudio)];
                    }else{
                        interact.types = @[@(NIMNetCallMediaTypeAudio)];
                    }
                    [interact show];
                }
            }
            break;
            
        case NTESLiveActionTypeShare://分享
            break;
            
        default:
            break;
    }
}

- (void)onClosePlaying{
    [DCURLRouter dismissViewControllerAnimated:YES completion:nil];
}

- (void)onCloseBypassing{
    [NTESLiveManager sharedLiveManager].connectorOnMic = nil;
    [self.innerView switchToWaitingUI];
    [self requestPlayStream];
    [[NIMAVChatSDK sharedSDK].netCallManager leaveMeeting:self.handler.currentMeeting];
}

#pragma mark NIMNetCallManagerDelegate
- (void)onUserJoined:(NSString *)uid meeting:(NIMNetCallMeeting *)meeting{
    SHLog(@"on user joined uid %@",uid);
}

- (void)onUserLeft:(NSString *)uid meeting:(NIMNetCallMeeting *)meeting{
    SHLog(@"on user left %@",uid);
    //如果是遇到主播退出了的情况，则自己默默退出去
    [SVProgressHUD showInfo:@"连接已断开"];
    [[NIMAVChatSDK sharedSDK].netCallManager leaveMeeting:self.handler.currentMeeting];
    [NTESLiveManager sharedLiveManager].connectorOnMic = nil;
}

- (void)onMeetingError:(NSError *)error meeting:(NIMNetCallMeeting *)meeting{
    [SVProgressHUD showInfo:[NSString stringWithFormat:@"互动直播失败 code: %zd",error.code]];
    [NTESLiveManager sharedLiveManager].connectorOnMic = nil;
    [self.innerView switchToWaitingUI];
    [self requestPlayStream];
}

#pragma mark 远程视频YUV数据
- (void)onRemoteYUVReady:(NSData *)yuvData width:(NSUInteger)width height:(NSUInteger)height from:(NSString *)user{
    [self.innerView updateRemoteView:yuvData width:width height:height];
}

#pragma mark NTESInteractSelectDelegate  音视频连线
- (void)onSelectInteractType:(NIMNetCallMediaType)type{
    __weak typeof(self) weakSelf = self;
    [NTESUserUtil requestMediaCapturerAccess:type handler:^(NSError *error){
        if (error) {
            [SVProgressHUD showInfo:@"申请连麦失败，请检查网络和权限重新开启"];
        }else{
            weakSelf.connectingView = [[NTESAudienceConnectView alloc] initWithFrame:self.bounds];
            weakSelf.connectingView.delegate = weakSelf;
            weakSelf.connectingView.roomId = _chatroomId;
            weakSelf.connectingView.type = type;
            [weakSelf.connectingView show];
            
            NIMChatroomMember *me = [[NTESLiveManager sharedLiveManager] myInfo:_chatroomId];
            NIMChatroom *chatroom = [[NTESLiveManager sharedLiveManager] roomInfo:_chatroomId];
            NTESQueuePushData *data = [[NTESQueuePushData alloc] init];
            data.roomId = _chatroomId;
            data.ext = [@{@"style":@(type),
                          @"state":@(NTESLiveMicStateWaiting),
                          @"info":@{
                                  @"nick" : me.roomNickname.length? me.roomNickname : me.userId,
                                  @"avatar":me.roomAvatar.length? me.roomAvatar : @"avatar_default"}} jsonBody];
            data.uid = me.userId;
            
            [[NTESDemoService sharedService] requestMicQueuePush:data completion:^(NSError *error) {
                //应用服务器会做数量限制，保证队列人数有个最大值，目前为100
                if (!error){
                    //发一条自定义通知告诉主播我进队列了，主播最多同一时间接到100条通知，不用担心主播会被撑爆
                    NIMCustomSystemNotification *notification = [NTESSessionCustomNotificationConverter notificationWithPushMic:chatroom.roomId style:type];
                    NIMSession *session = [NIMSession session:chatroom.creator type:NIMSessionTypeP2P];
                    [[NIMSDK sharedSDK].systemNotificationManager sendCustomNotification:notification toSession:session completion:^(NSError * _Nullable error) {
                        if (error) {
                            [SVProgressHUD showInfo:@"申请失败,请重试"];
                            weakSelf.handler.isWaitingForAgreeConnect = NO;
                            [weakSelf.connectingView dismiss];
                            weakSelf.connectingView = nil;
                        }else{
                            //把自己加入的互动直播方式存起来
                            [NTESLiveManager sharedLiveManager].bypassType  = type;
                            //标记自己正在请求连麦
                            weakSelf.handler.isWaitingForAgreeConnect = YES;
                        }
                    }];
                } else{
                    switch (error.code) {
                        case NTESRemoteErrorCodeOverFlow:
                            [SVProgressHUD showInfo:@"连麦人数超过上限"];
                            break;
                        default:
                            [SVProgressHUD showInfo:@"连麦请求失败，请重试"];
                            break;
                    }
                    [weakSelf.connectingView dismiss];
                    weakSelf.connectingView = nil;
                }
            }];
        }
    }];
}

#pragma mark NTESAudienceConnectDelegate
#pragma mark 取消连线
- (void)onCancelConnect:(id)sender{
    NTESQueuePopData *data = [[NTESQueuePopData alloc] init];
    data.roomId = _chatroomId;
    data.uid = [[NIMSDK sharedSDK].loginManager currentAccount];
    [[NTESDemoService sharedService] requestMicQueuePop:data completion:nil];
    
    //标记自己不再请求连麦
    self.handler.isWaitingForAgreeConnect = NO;
    self.connectingView = nil;
    
    NIMChatroom *chatroom = [[NTESLiveManager sharedLiveManager] roomInfo:_chatroomId];
    //发一条自定义通知告诉主播我退出队列了，主播最多同一时间接到100条通知，不用担心主播会被撑爆
    NIMCustomSystemNotification *notification = [NTESSessionCustomNotificationConverter notificationWithPopMic:_chatroomId];
    NIMSession *session = [NIMSession session:chatroom.creator type:NIMSessionTypeP2P];
    [[NIMSDK sharedSDK].systemNotificationManager sendCustomNotification:notification toSession:session completion:nil];
}

#pragma mark NIMChatManagerDelegate
- (void)willSendMessage:(NIMMessage *)message{
    switch (message.messageType) {
        case NIMMessageTypeText:
            [self.innerView addMessages:@[message]];
            break;
        case NIMMessageTypeCustom:
        {
            NIMCustomObject *object = message.messageObject;
            id<NIMCustomAttachment> attachment = object.attachment;
            if ([attachment isKindOfClass:[NTESPresentAttachment class]]) {
                [self.innerView addPresentMessages:@[message]];
            }
        }
            break;
        default:
            break;
    }
}

- (void)onRecvMessages:(NSArray *)messages{
    for (NIMMessage *message in messages) {
        if (![message.session.sessionId isEqualToString:_chatroomId]
            && message.session.sessionType == NIMSessionTypeChatroom) {
            //不属于这个聊天室的消息
            return;
        }
        switch (message.messageType) {
            case NIMMessageTypeText:
                [self.innerView addMessages:@[message]];
                break;
            case NIMMessageTypeCustom:
            {
                NIMCustomObject *object = message.messageObject;
                id<NIMCustomAttachment> attachment = object.attachment;
                if ([attachment isKindOfClass:[NTESPresentAttachment class]]) {
                    [self.innerView addPresentMessages:@[message]];
                }
                else if ([attachment isKindOfClass:[NTESLikeAttachment class]]) {
                    [self.innerView fireLike];
                }
                else if ([attachment isKindOfClass:[NTESMicConnectedAttachment class]] || [attachment isKindOfClass:[NTESDisConnectedAttachment class]]) {
                    [self.handler dealWithBypassMessage:message];
                }
            }
                break;
            case NIMMessageTypeNotification:{
                [self.handler dealWithNotificationMessage:message];
            }
                break;
            default:
                break;
        }
    }
}

#pragma mark NIMChatroomManagerDelegate
- (void)chatroom:(NSString *)roomId beKicked:(NIMChatroomKickReason)reason{
    if ([roomId isEqualToString:_chatroomId]) {
        [SVProgressHUD showInfo:@"你被踢出聊天室"];
        [[NIMSDK sharedSDK].chatroomManager exitChatroom:roomId completion:nil];
        [DCURLRouter dismissViewControllerAnimated:YES completion:nil];
    }
}

- (void)chatroom:(NSString *)roomId connectionStateChanged:(NIMChatroomConnectionState)state{
    if (state == NIMChatroomConnectionStateEnterOK) {
        //获取连麦队列状态
        [self requestMicQueue];
    }
}

#pragma mark  NIMSystemNotificationManagerDelegate
- (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification{
    NSString *content  = notification.content;
    NSDictionary *dict = [content jsonObject];
    NTESLiveCustomNotificationType type = [dict jsonInteger:@"command"];
    switch (type) {
        case NTESLiveCustomNotificationTypeAgreeConnectMic:
        case NTESLiveCustomNotificationTypeForceDisconnect:
            [self.handler dealWithBypassCustomNotification:notification];
            break;
        default:
            break;
    }
}

#pragma mark NTESLiveAudienceHandlerDelegate
- (void)didUpdateUserOnMic{
    if(![[NTESLiveManager sharedLiveManager].connectorOnMic.uid isEqualToString:[[NIMSDK sharedSDK].loginManager currentAccount]]
       && self.player.playbackState == NELPMoviePlaybackStatePlaying){
        //即普通连麦观众,并且是正在推拉流的状态,则整个UI更新一把
        [self.innerView switchToPlayingUI];
    }else{
        //其他情况下更新名字就可以了
        [self.innerView updateUserOnMic];
    }
}

- (void)willStartByPassing:(NTESPlayerShutdownCompletion)completion{
    [self.player.view removeFromSuperview];
    [self shutdown:^{
        completion();
    }];
    [UIApplication sharedApplication].idleTimerDisabled = YES;
}

- (void)didStartByPassing{
    NTESMicConnector *connector = [NTESMicConnector me:_chatroomId];
    [self.innerView switchToBypassingUI:connector];
    [self.connectingView dismiss];
    self.connectingView = nil;
    self.isPlaying = NO;
}

- (void)didStopByPassing{
    [NTESLiveManager sharedLiveManager].connectorOnMic = nil;
    [self.innerView switchToWaitingUI];
    [self requestPlayStream];
}

- (void)didUpdateLiveType:(NTESLiveType)type{
    //说明主播重新进来了，这种情况下，刷下type就好了。
    [NTESLiveManager sharedLiveManager].type = type;
    if (type == NTESLiveTypeInvalid) {
        //发出全局播放结束通知
        [self shutdown:nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:NTESLivePlayerPlaybackFinishedNotification object:nil userInfo:@{NELivePlayerPlaybackDidFinishReasonUserInfoKey:@(NELPMovieFinishReasonPlaybackEnded)}];
    }
}

-(void)didUpdateLiveOrientation:(NIMVideoOrientation)orientation{

}

- (void)joinMeetingError:(NSError *)error{
    [self didStopByPassing];
}

#pragma mark - Notification
- (void)playerDidPlay:(NSNotification *)notification{
    [self.innerView switchToPlayingUI];
    for (UIView * view in self.canvas.subviews) {
        if ([view isKindOfClass:NSClassFromString(@"IJKSDLGLView")]) {
            view.contentMode = UIViewContentModeScaleAspectFill;
            break;
        }
    }
    self.isPlaying = YES;
}

- (void)playerDidPlay{
    [self adjustPlayerView];
}

- (void)playbackFinshed:(NSNotification *)notification{
    switch ([[[notification userInfo] valueForKey:NELivePlayerPlaybackDidFinishReasonUserInfoKey] intValue]){
        case NELPMovieFinishReasonPlaybackEnded:
            self.isPlaying = NO;
            [self.innerView switchToEndUI];
            break;
        case NELPMovieFinishReasonPlaybackError:
            if (self.isPlaying) {
                [self.innerView switchToLinkingUI];
            }else{
                [self.innerView switchToEndUI];
            }
            break;
        case NELPMovieFinishReasonUserExited:
            break;
        default:
            break;
    }
}

- (void)livePlayerWillBecomeActive:(NSNotification *)notification{
    [self.player play];
}

- (void)livePlayerDidPreparedToPlay:(NSNotification *)notification{
    [self.player setMute:self.isMute];
    [self.player play];
}

- (void)livePlayerPlayBackFinished:(NSNotification*)notification{
    switch ([[[notification userInfo] valueForKey:NELivePlayerPlaybackDidFinishReasonUserInfoKey] intValue]){
        case NELPMovieFinishReasonPlaybackEnded:{
            [self retry:10];
            break;
        }
        case NELPMovieFinishReasonPlaybackError:{
            [self retry:5];
            break;
        }
        case NELPMovieFinishReasonUserExited:
            break;
            
        default:
            break;
    }
}

- (void)livePlayerReleaseSueecssed:(NSNotification *)notification{
    dispatch_sync(dispatch_get_main_queue(), ^{
        _isShutdowning = NO;
        [self fireShutdownHandlers];
        if (_isNextPlayer) {
             [self startPlay];
        }
    });
}

- (void)livePlayerWillEnterForeground:(NSNotification *)notification{
    [self.player play];
}


- (void)adjustPlayerView{
    NELPVideoInfo info;
    [self.player getVideoInfo:&info];
    CGSize size = CGSizeMake(info.width, info.height);
    if (!CGSizeEqualToSize(size, CGSizeZero)) {
        if ([self videoInfoIsFromPC:size])
        {
            [self adjustPlayerViewFromPC:size];
        }
        else
        {
            [self adjustPlayerViewFromMobile:size];
        }
    }
    self.player.view.userInteractionEnabled = NO;
}

- (BOOL)videoInfoIsFromPC:(CGSize)size{
    return size.width/size.height >= 4/3;  //大于等于4:3的屏幕，都认为是PC屏
}

- (void)adjustPlayerViewFromMobile:(CGSize)size{
    UIView *superview = self.player.view.superview;
    
    CGFloat scaleW = superview.width/size.width;
    CGFloat scaleH = superview.height/size.height;
    CGFloat scale  = scaleW > scaleH? scaleW : scaleH;
    CGFloat width  = size.width * scale;
    CGFloat height = size.height * scale;
    self.player.view.frame = CGRectMake(0, 0, width, height);
    
    //放到右下角，保证小屏幕不会被裁掉
    self.player.view.bottom = superview.bottom;
    self.player.view.right  = superview.width;
}

- (void)adjustPlayerViewFromPC:(CGSize)size{
    //因为 ScalingMode 本身是 NELPMovieScalingModeAspectFit，会黑边填充，所以放大到和 superview 一样大就好了
    UIView *superview = self.player.view.superview;
    self.player.view.frame = superview.bounds;
}

- (void)enterChatroom{
    __weak typeof(self) weakSelf = self;
    NIMChatroomEnterRequest *request = [[NIMChatroomEnterRequest alloc] init];
    request.roomId = _chatroomId;
    [[NIMSDK sharedSDK].chatroomManager enterChatroom:request completion:^(NSError * _Nullable error, NIMChatroom * _Nullable chatroom, NIMChatroomMember * _Nullable me) {
        if (!error) {
            [[NTESLiveManager sharedLiveManager] cacheMyInfo:me roomId:request.roomId];
            [[NTESLiveManager sharedLiveManager] cacheChatroom:chatroom];
            weakSelf.handler = [[NTESLiveAudienceHandler alloc] initWithChatroom:chatroom];
            weakSelf.handler.delegate = self;
            [weakSelf.innerView refreshChatroom:chatroom];
            if (weakSelf.isPlaying) {
                //如果开始播放了，就刷一遍播放界面，否则什么事也不做
                [weakSelf.innerView switchToPlayingUI];
            }
            
        }else{
            [SVProgressHUD showInfo:@"直播间进入失败，请确认ID是否正确"];
        }
    }];
}


- (void)doExitLive{
    [[NIMSDK sharedSDK].chatroomManager exitChatroom:_chatroomId completion:nil];
    [[NIMAVChatSDK sharedSDK].netCallManager leaveMeeting:self.handler.currentMeeting];
    [self shutdown:nil];
}

- (void)shutdown:(NTESLivePlayerShutdownHandler)handler{
    if (handler) {
        [self.shutdownHandlers addObject:handler];
    }
    [self shutdown];
}


- (void)requestPlayStream{
    if (self.player.playbackState == NELPMoviePlaybackStatePlaying) {
        return;
    }
    __weak typeof(self) wself = self;
    [[NTESDemoService sharedService] requestPlayStream:_chatroomId completion:^(NSError *error, NSString *playStreamUrl,NTESLiveType liveType,NIMVideoOrientation orientation) {
        NSString *me = [[NIMSDK sharedSDK].loginManager currentAccount];
        if ([[NTESLiveManager sharedLiveManager].connectorOnMic.uid isEqualToString:me]) {
            //请求拉流地址回来后，发现自己已经上麦了，则不需要再开启播放器
            return;
        }
        if (!error) {
            [NTESLiveManager sharedLiveManager].type = liveType;
            [wself startPlay];
        }else{
            //拉地址没成功，则过5秒重试
            NSTimeInterval delay = 5.f;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [wself requestPlayStream];
            });
        }
    }];
}

- (void)requestMicQueue{
    __weak typeof(self) weakSelf = self;
    [[NIMSDK sharedSDK].chatroomManager fetchChatroomQueue:_chatroomId completion:^(NSError * _Nullable error, NSArray<NSDictionary<NSString *,NSString *> *> * _Nullable info) {
        if (!error){
            [NTESLiveManager sharedLiveManager].connectorOnMic = nil;
            for (NSDictionary *pair in info) {
                NTESMicConnector *connector = [[NTESMicConnector alloc] initWithDictionary:pair];
                if (connector.state == NTESLiveMicStateConnected) {
                    [NTESLiveManager sharedLiveManager].connectorOnMic = connector;
                }
            }
            if (![[NTESLiveManager sharedLiveManager].connectorOnMic.uid isEqualToString:[[NIMSDK sharedSDK].loginManager currentAccount]]) {
                if (weakSelf.isPlaying) {
                    [weakSelf.innerView switchToPlayingUI];
                }else{
                    [weakSelf.innerView switchToLinkingUI];
                }
            }
        }else{
            [SVProgressHUD showInfo:[NSString stringWithFormat:@"%@", error]];
        }
    }];
}


- (void)dealloc{
    [self.player.view removeFromSuperview];
    [self shutdown];
    [[NIMSDK sharedSDK].chatroomManager removeDelegate:self];
    [[NIMSDK sharedSDK].chatManager removeDelegate:self];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[NTESLiveManager sharedLiveManager] stop];
    
    if (self.handler.isWaitingForAgreeConnect) {
        [self onCancelConnect:nil];
    }
}


@end
